package com.qubaopen.core.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dom4j.Document;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.web.context.ServletContextAware;

import com.qubaopen.core.beans.SysConfigData;

public class AppUtil implements ApplicationContextAware, ServletContextAware {
	private static Log logger = LogFactory.getLog(AppUtil.class);

	private static ServletContext servletContext = null;
	private static ApplicationContext appContext;

	private static SysConfigData sysConfig = null;
	private static Document menuDocument = null;

	public static SysConfigData getSystemConfig() {
		return sysConfig;
	}

	@Override
	public void setApplicationContext(ApplicationContext context)
			throws BeansException {
		appContext = context;
	}

	@Override
	public void setServletContext(ServletContext context) {
		servletContext = context;
	}

	public static void init() {
		sysConfig = (SysConfigData) getBean("sysConfigData");
	}

	public static Document getMenuDocument() {
		return menuDocument;
	}

	public static void setMenuDocument(Document menuDocument) {
		AppUtil.menuDocument = menuDocument;
	}

	public static Object getBean(String beanId) {
		return appContext.getBean(beanId);
	}

	/**
	 * 获取ServletContext根目录绝对路径
	 * 
	 * @return
	 */
	public static String getSystemPath() {
		String sysPath = servletContext.getRealPath("/");
		if (!StringUtils.endsWith(sysPath, "/")) {
			sysPath = sysPath + "/";
		}

		return sysPath;
	}

	/**
	 * 根据当前时间和随机数对文件进行重命名
	 * 
	 * @param fileName
	 *            原文件名
	 * @return
	 */
	public static String renameFileByRandom(String fileName) {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
		String formatDate = format.format(new Date());
		int random = new Random().nextInt(10000);
		String filePrefix = new StringBuffer().append(formatDate)
				.append(random).toString();

		String newFileName = filePrefix + "."
				+ StringUtils.substringAfterLast(fileName, ".");

		return newFileName;
	}

	/**
	 * 生成指定文件下载
	 */
	public static void buildFileDownloadRespone(HttpServletResponse response,
			String fileName) {

		OutputStream output = null;
		FileInputStream input = null;

		try {
			File file = new File(fileName);

			String baseName = StringUtils.substring(fileName,
					StringUtils.lastIndexOf(fileName, "/"));

			response.reset();
			response.setContentType("application/octet-stream");
			response.setHeader("content-disposition", "attachment;filename="
					+ baseName);

			int fileLength = (int) file.length();
			if (fileLength > 0) {
				response.setContentLength(fileLength);
			}

			output = response.getOutputStream();
			input = new FileInputStream(file);

			byte[] buf = new byte[4 * 1024]; // 4K buffer
			int bytesRead;

			while ((bytesRead = input.read(buf)) != -1) {
				output.write(buf, 0, bytesRead);
			}

			output.flush();
			output.close();
			input.close();
		} catch (Exception e) {
			//
		} finally {
			try {
				if (input != null) {
					input.close();
				}

				if (output != null) {
					output.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static String getClientIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("X-Forwarded-For");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_CLIENT_IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}

		// get client ip
		InetAddress inet;
		try {
			inet = InetAddress.getByName(ip);
			ip = inet.getHostAddress();
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}

		return ip;
	}

	public static String getErrorMessage(Exception e) {
		StringBuffer sb = new StringBuffer();
		sb.append(e.toString() + "\n");
		for (StackTraceElement st : e.getStackTrace()) {
			sb.append(st.getClassName() + "  " + st.getMethodName() + "  "
					+ st.getLineNumber() + "\n");
		}
		return sb.toString();
	}
}
